﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace location_demo1
{
    public partial class FrmMain : Form
    {
        uint dist0, dist1, dist2, Tagx, Tagy;
        uint ch4_value, co_value;
        //byte[] readBuffer;
        SerialPort serialPort1 = new SerialPort();
        private List<byte> buffer = new List<byte>(4096);
        //byte[] buf;
        //int temp;
        public FrmMain()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        private void showData(object sender, EventArgs e)
        {

            tagz.Text = "0";
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            if (Serial_button.Text == "打开串口")
            {
                try
                {
                    //serialPort1.PortName = comboBox2.Text;//获取端口号
                    serialPort1.PortName = "COM36";//获取端口号
                    serialPort1.BaudRate = Convert.ToInt32(comboBox1.Text);
                    serialPort1.DataBits = 8;
                    serialPort1.Parity = Parity.None;
                    serialPort1.StopBits = StopBits.One;
                    serialPort1.Open();
                    Serial_button.Text = "关闭串口";
                    serialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);//数据接收时间
                    serialPort1.Write("123");
                }
                catch
                {
                    MessageBox.Show("串口打开错误");
                }
            }
            else
            {
                try
                {
                    serialPort1.Close();
                    Serial_button.Text = "打开串口";
                }
                catch { }
            }
        }

        /// <summary>
        /// 数据接收函数
        /// （接收串口数据的委托方法实现）
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //tbDist0.Text = "hhh";
            try
            {
                byte[] readBuffer = null;
                int cnt = serialPort1.BytesToRead;
                byte[] buf = new byte[cnt];
                serialPort1.Read(buf, 0, cnt);//向串口中读取数据
                buffer.AddRange(buf);//将buf的数据追加，缓存到buffer
                while (buffer.Count >= 3)//至少包含3字节,帧头1B，长度1B，校验和1B
                {
                    int num = 0;
                    if (buffer[0] == 0xFE)// 传输数据有帧头，用于判断
                    {
                        int len = buffer[1];//数据长度1B（hex）=27(10)
                        if (buffer.Count < len + 3)
                        {
                            break;//没有接收完成
                        }
                        readBuffer = new byte[len + 3];
                        num = len + 3;
                        buffer.CopyTo(0, readBuffer, 0, len + 3);//得到完整的数据，复制到readBuffer中
                        byte parity_num = 0;
                        for (int i = 2; i < len + 3 - 1; i++)
                        {
                            parity_num += readBuffer[i];
                        }
                        if (parity_num != readBuffer[len + 3 - 1])//校验失败  /*超出数组范围*/
                        {
                            MessageBox.Show("数据包错误");
                            continue;
                        }
                        //数据解析
                        dist0 = 0; dist1 = 0; dist2 = 0; Tagx = 0; Tagy = 0;
                        ch4_value = 0; co_value = 0;
                        //dist0
                        if (readBuffer[2] == 0)
                        {
                            Console.WriteLine("id:" + readBuffer[2]);
                            dist0 |= 0xff000000 & (((uint)readBuffer[3]) << 24);
                            dist0 |= 0x00ff0000 & (((uint)readBuffer[4]) << 16);
                            dist0 |= 0x0000ff00 & (((uint)readBuffer[5]) << 8);
                            dist0 |= 0x000000ff & (((uint)readBuffer[6]) << 0);
                            /*最开始显示不了，因为线程访问冲突，在构造函数里加Control.CheckForIllegalCrossThreadCalls = false;才能访问*/
                            Console.WriteLine("dist0:" + dist0);
                            tbDist0.Text = Convert.ToString(Convert.ToDouble(dist0) / 100);
                        }
                        //dist1
                        if (readBuffer[7] == 1)
                        {
                            Console.WriteLine("id:" + readBuffer[7]);
                            dist1 |= 0xff000000 & (((uint)readBuffer[8]) << 24);
                            dist1 |= 0x00ff0000 & (((uint)readBuffer[9]) << 16);
                            dist1 |= 0x0000ff00 & (((uint)readBuffer[10]) << 8);
                            dist1 |= 0x000000ff & (((uint)readBuffer[11]) << 0);
                            tbDist1.Text = Convert.ToString(Convert.ToDouble(dist1) / 100);
                            Console.WriteLine("dist1:" + dist1);
                        }
                        //dist2
                        if (readBuffer[12] == 2)
                        {
                            Console.WriteLine("id:" + readBuffer[12]);
                            dist2 |= 0xff000000 & (((uint)readBuffer[13]) << 24);
                            dist2 |= 0x00ff0000 & (((uint)readBuffer[14]) << 16);
                            dist2 |= 0x0000ff00 & (((uint)readBuffer[15]) << 8);
                            dist2 |= 0x000000ff & (((uint)readBuffer[16]) << 0);
                            tbDist2.Text = Convert.ToString(Convert.ToDouble(dist2) / 100);
                            Console.WriteLine("dist2:" + dist2);
                        }
                        //ch4
                        ch4_value |= 0x0000ff00 & (((uint)readBuffer[17]) << 8);
                        ch4_value |= 0x000000ff & (((uint)readBuffer[18]) << 0);
                        tbMQ7.Text = Convert.ToString(Convert.ToDouble(ch4_value) / 100);
                        //Console.WriteLine("ch4_value:" + ch4_value);
                        //co
                        co_value |= 0x0000ff00 & (((uint)readBuffer[19]) << 8);
                        co_value |= 0x000000ff & (((uint)readBuffer[20]) << 0);
                        tbMQ2.Text = Convert.ToString(Convert.ToDouble(co_value) / 100);
                        //Console.WriteLine("co_value:" + co_value);
                        //tagx
                        Tagx |= 0xff000000 & (((uint)readBuffer[21]) << 24);
                        Tagx |= 0x00ff0000 & (((uint)readBuffer[22]) << 16);
                        Tagx |= 0x0000ff00 & (((uint)readBuffer[23]) << 8);
                        Tagx |= 0x000000ff & (((uint)readBuffer[24]) << 0);
                        //textBox10.Text = Convert.ToString(Convert.ToDouble(Tagx)/100);
                        //textBox10.Text = "1.25";
                        double tx = Convert.ToDouble(Tagx) / 100;
                        textBox11.Text = Convert.ToString(tx);
                        //Console.WriteLine("Tagx:" + Convert.ToDouble(Tagx));
                        //tagy
                        Tagy |= 0xff000000 & (((uint)readBuffer[25]) << 24);
                        Tagy |= 0x00ff0000 & (((uint)readBuffer[26]) << 16);
                        Tagy |= 0x0000ff00 & (((uint)readBuffer[27]) << 8);
                        Tagy |= 0x000000ff & (((uint)readBuffer[28]) << 0);
                        double ty = Convert.ToDouble(Tagy) / 100;
                        tagy.Text = Convert.ToString(ty);
                        tagz.Text = "0";
                        //Console.WriteLine("Tagy:" + Tagy);
                        //通过设置属性坐标移动标签位置\
                        int x = Convert.ToInt32((tx*660/720)*100 );
                        int y = Convert.ToInt32((ty*480/500)*100 );
                        pictureBox5.Location = new Point(x, y);
                        Console.WriteLine("tx:" + Convert.ToInt32(x));
                        Console.WriteLine("ty:" + Convert.ToInt32(y));
                        //pictureBox5.Location = new Point(0, 0);

                        buffer.RemoveRange(0, len + 3);//从缓冲区中清除
                                                       //触发外部处理接收消息事件
                    }
                    else//帧头不正确。清除
                    {
                        buffer.RemoveAt(0);
                    }
                }
            }
            catch
            {
                MessageBox.Show("异常");
            }
            //Console.WriteLine("Data Received:"+data);
        }
 
        private void label11_Click(object sender, EventArgs e)
        {

        }

        private void label13_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void label15_Click(object sender, EventArgs e)
        {

        }

        private void tbDist0_TextChanged(object sender, EventArgs e)
        {
            tbDist0.Text = Convert.ToString(dist0);
            Console.WriteLine("ok");

        }

        /// <summary>
        /// 扫描串口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click_1(object sender, EventArgs e)
        {
            SearchAnAddSerialToCombobox(serialPort1, comboBox2);
        }

        private void SearchAnAddSerialToCombobox(SerialPort mPort, ComboBox mBox)
        {
            //将可用的串口号添加到ComboBox
            string[] NmberOfport = new string[100];//最多容纳20个，太多会卡，影响效率
            string MidString1;//中间数组，用于缓存
            mBox.Items.Clear();//清空combobox的内容
            for (int i = 1; i < 100; i++)
            {
                try //核心是靠try和catch 完成遍历
                {
                    MidString1 = "COM" + i.ToString();  //把串口名字赋给MidString1
                    mPort.PortName = MidString1;       //把MidString1赋给 MyPort.PortName 
                    mPort.Open();                      //如果失败，后面代码不执行？？
                    NmberOfport[i - 1] = MidString1;    //依次把MidString1的字符赋给NmberOfport
                    mBox.Items.Add(MidString1);        //打开成功，添加到下列列表
                    mPort.Close();                     //关闭
                    mBox.Text = NmberOfport[i - 1];    //显示最后扫描成功那个串口
                }
                catch { };
            }
        }
    }
}
